package top.kaoshanji.ch01.collecting;

import com.google.common.io.Resources;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 代码清单 ch01-04：将流中的元素收集到另一个目标中(1.8节)
 * author kaoshanji
 * ^_^
 * create time 2024/12/5 14:58
 */
public class CollectingResults {

    private static final Logger logger = LogManager.getLogger(CollectingResults.class);

    static final String FILE_NAME = "gutenberg/alice30.txt";

    public static void main(String[] args) throws IOException {
        logger.info("...代码清单 ch01-04：将流中的元素收集到另一个目标中(1.8节)...");

        // 【例1】迭代器对象
        Iterator<Integer> iter = Stream.iterate(0, n -> n + 1).limit(10).iterator();
        while (iter.hasNext()) {
            System.out.println(iter.next());
        }

        // 【例2】将流收集到 指定类型的数组
        Integer[] number3 = Stream.iterate(0, n -> n + 1).limit(10).toArray(Integer[]::new);
        System.out.println("Integer array: " + number3);

        // 【例3】将流收集到 Set对象
        Set<String> noVowelSet = noVowels().collect(Collectors.toSet());;
        show("noVowelSet", noVowelSet);

        // 【例4】将流收集到 TreeSet对象
        TreeSet<String> noVowelTreeSet = noVowels().collect(Collectors.toCollection(TreeSet::new));
        show("noVowelTreeSet", noVowelTreeSet);

        // 【例5】将流收集到 字符串
        String result = noVowels().limit(10).collect(Collectors.joining());
        System.out.println("Joining: " + result);

        // 【例6】将流收集到 字符串元素之间增加分隔符
        result = noVowels().limit(10).collect(Collectors.joining(", "));
        System.out.println("Joining with commas: " + result);

        // 【例7】将流的结果约简为总和、数量、平均值、最大值或最小值
        IntSummaryStatistics summary = noVowels().collect(Collectors.summarizingInt(String::length));
        double averageWordLength = summary.getAverage();
        double maxWordLength = summary.getMax();
        System.out.println("Average word length: " + averageWordLength);
        System.out.println("Max word length: " + maxWordLength);
        System.out.println("forEach:");
        noVowels().limit(10).forEach(System.out::println);

    }

    public static Stream<String> noVowels() throws IOException {

        String fileContent = Resources.toString(Resources.getResource(FILE_NAME), StandardCharsets.UTF_8);
        List<String> wordList = List.of(fileContent.split("\\PL+"));

        Stream<String> words = wordList.stream();
        return words.map(s -> s.replaceAll("[aeiouAEIOU]", ""));
    }

    public static <T> void show(String lable, Set<T> set) {

        System.out.println(lable + ": " + set.getClass().getName());
        System.out.println("[" + set.stream().limit(10).map(Objects::toString).collect(Collectors.joining(", ")) + "]");

    }


}
